home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / tools / amigaos4_only / fracblank / source / fraccontrol.c < prev    next >
C/C++ Source or Header  |  2004-08-03  |  10KB  |  322 lines

  1. /*
  2. **  FracBlank - AmigaDOS 2.04 commodities utility screenblanker
  3. **
  4. **  Copyright © 1991-1995 by Olaf `Olsen' Barthel
  5. **    All Rights Reserved
  6. **
  7. **  Cosmic flame fractal code derived from xlock source code
  8. **
  9. **  Copyright © 1988-1991 by Patrick J. Naughton.
  10. */
  11.  
  12. #include <math.h>
  13.  
  14. #include <proto/dos.h>
  15. #include <proto/exec.h>
  16. #include <proto/graphics.h>
  17. #include <proto/intuition.h>
  18.  
  19. #include "Frac.h"
  20. #include "FracControl.h"
  21.  
  22. // BlankerEntry data
  23.  
  24. ULONG Pen;
  25. WORD  Width,
  26.       Height;
  27.  
  28. struct Task     *BlankTask;
  29. struct Screen   *BlankScreen;
  30. struct Window   *BlankWindow;
  31. struct RastPort *RPort;
  32. struct ViewPort *VPort;
  33.  
  34. // In case we need to rescale things
  35.  
  36. double VerticalScale;
  37.  
  38. // Colour table data
  39.  
  40. UBYTE Red[255],
  41.       Green[255],
  42.       Blue[255];
  43. WORD  MaxColour,
  44.       Wheel;
  45.  
  46. ColourTable *Colours;
  47.  
  48. // Some kind of a semaphore to tell the blank task to stop drawing
  49.  
  50. BYTE StopDrawing = FALSE;
  51.  
  52. // Prototypes
  53.  
  54. void hsvramp(double h1, double s1, double b1, double h2, double s2, double b2, int count, UBYTE *red, UBYTE *green, UBYTE *blue);
  55. void hsv2rgb(double H, double S, double V, UBYTE *r, UBYTE *g, UBYTE *b);
  56.  
  57. /* BlankerControlEntry():
  58.  *
  59.  *  The screen blanker control task.
  60.  */
  61.  
  62. VOID BlankerControlEntry() {
  63.  
  64.   ULONG SignalSet;
  65.  
  66.   IExec->Forbid();
  67.  
  68.   // Ring back...
  69.  
  70.   IExec->Signal((struct Task *)MainProcess,SIG_HANDSHAKE);
  71.  
  72.   for(;;) {
  73.     // Wait for something to happen
  74.     SignalSet = IExec->Wait(SIG_BREAK | SIG_START | SIG_CHANGE | SIG_FINISH);
  75.     // Remove both the screen and the blanker task?
  76.     if (SignalSet & (SIG_BREAK | SIG_FINISH)) {
  77.       IExec->ObtainSemaphore(&BlankSemaphore);
  78.       if (BlankScreen) IIntuition->ScreenToBack(BlankScreen);
  79.       // Remove the blanker task
  80.       if (BlankTask) {
  81.         IExec->SetSignal(0,SIG_HANDSHAKE);
  82.         // Tell the blanker task to shut down
  83.         IExec->Signal(BlankTask,SIG_BREAK);
  84.         // Move the blanker task priority up,
  85.         // we don't want the low priority task
  86.         // to wait until some high priority task
  87.         // yields CPU time
  88.         IExec->SetTaskPri(BlankTask,127);
  89.         // Wait for handshake signal...
  90.         IExec->Wait(SIG_HANDSHAKE);
  91.         // He's dead, Jim
  92.         BlankTask = NULL;
  93.       }
  94.       // Close the blanker screen
  95.       if (BlankScreen) {
  96.         IIntuition->ScreenToBack(BlankScreen);
  97.         IIntuition->CloseWindow(BlankWindow);
  98.         BlankWindow = NULL;
  99.         IIntuition->CloseScreen(BlankScreen);
  100.         BlankScreen = NULL;
  101.       }
  102.       IExec->ReleaseSemaphore(&BlankSemaphore);
  103.       SignalSet &= ~(SIG_CHANGE | SIG_START);
  104.     }
  105.     // Leave the town?
  106.     if (SignalSet & SIG_FINISH) break;
  107.     // Start the screen blanker?
  108.     if (SignalSet & SIG_START) {
  109.       // Is the screen already open?
  110.       if (!BlankScreen) {
  111.         ULONG LocalID;
  112.         // Use the default public screen display ID
  113.         // if necessary
  114.         if (DisplayID == INVALID_ID || (IGraphics->ModeNotAvailable(DisplayID) & ~DI_AVAIL_NOTWITHGENLOCK)) {
  115.           struct Screen *PubScreen = IIntuition->LockPubScreen(NULL);
  116.           if (PubScreen) {
  117.             LocalID = IGraphics->GetVPModeID(&PubScreen->ViewPort);
  118.             IIntuition->UnlockPubScreen(NULL,PubScreen);
  119.           }
  120.           else LocalID = INVALID_ID;
  121.         }
  122.         else LocalID = DisplayID;
  123.         // Did we get a valid ID?
  124.         if (LocalID != INVALID_ID) {
  125.           WORD   LocalDepth;
  126.           struct DimensionInfo  DimensionInfo;
  127.           struct DisplayInfo  DisplayInfo;
  128.           // Choose the right display depth
  129.           LocalDepth = Depth;
  130.           if (IGraphics->GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(DimensionInfo),DTAG_DIMS,LocalID)) {
  131.             if (!LocalDepth) {
  132.               if ((LocalDepth = DimensionInfo.MaxDepth) > 8) LocalDepth = 8;
  133.             }
  134.             else {
  135.               if (LocalDepth > DimensionInfo.MaxDepth) LocalDepth = DimensionInfo.MaxDepth;
  136.             }
  137.           }
  138.           else {
  139.             if (!LocalDepth) LocalDepth = 2;
  140.           }
  141.           // Compensate for the display aspect ratio
  142.           if (IGraphics->GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(DisplayInfo),DTAG_DISP,LocalID)) {
  143.             if (DisplayInfo.Resolution.y) {
  144.               double x,y;
  145.               x = (double)DisplayInfo.Resolution.x;
  146.               y = (double)DisplayInfo.Resolution.y;
  147.               VerticalScale = x / y;
  148.             }
  149.             else VerticalScale = 1.0;
  150.           }
  151.           else VerticalScale = 1.0;
  152.           // Set the colour table to black
  153.           MaxColour = (1 << LocalDepth) - 1;
  154.           Colours->NumColours = MaxColour + 1;
  155.           memset(&Colours->Entry[0],0,256 * sizeof(ColourEntry));
  156.           // Now open the screen and the window
  157.           IExec->ObtainSemaphore(&BlankSemaphore);
  158.           if (BlankScreen = IIntuition->OpenScreenTags(NULL,
  159.                                                        SA_Behind,    TRUE,
  160.                                                        SA_Quiet,     TRUE,
  161.                                                        SA_DisplayID, LocalID,
  162.                                                        SA_Overscan,  OSCAN_MAX,
  163.                                                        SA_Depth,     LocalDepth,
  164.                                                        SA_ShowTitle, FALSE,
  165.                                                        SA_BackFill, &ScreenHook,
  166.                                                        SA_Colors32,  Colours,
  167.                                                        SA_Draggable, FALSE,
  168.                                                        SA_Exclusive, TRUE,
  169.                                                        TAG_DONE)) {
  170.             VPort  = &BlankScreen->ViewPort;
  171.             Width  = BlankScreen->Width;
  172.             Height = BlankScreen->Height;
  173.             // To keep the ball rolling...
  174.             if ((DisplayDepth = LocalDepth) == 1) {
  175.               MaxColour = 255;
  176.               Colours->NumColours = 2;
  177.             }
  178.             // Create a nice colour table
  179.             hsvramp(0.0,1.0,1.0,1.0,1.0,1.0,MaxColour,Red,Green,Blue);
  180.             Wheel = Random(MaxColour);
  181.             RotatePalette();
  182.             // Open the window
  183.             if (BlankWindow = IIntuition->OpenWindowTags(NULL,
  184.                                                          WA_Left,         0,
  185.                                                          WA_Top,          0,
  186.                                                          WA_Width,        Width,
  187.                                                          WA_Height,       Height,
  188.                                                          WA_Backdrop,     TRUE,
  189.                                                          WA_Borderless,   TRUE,
  190.                                                          WA_Pointer,      Pointer,
  191.                                                          WA_CustomScreen, BlankScreen,
  192.                                                          WA_Activate,     TRUE,
  193.                                                          WA_RMBTrap,      TRUE,
  194.                                                          WA_BackFill,    &WindowHook,
  195.                                                          TAG_DONE)) {
  196.               RPort = BlankWindow->RPort;
  197.               IGraphics->SetABPenDrMd(RPort,Pen = 1,0,JAM1);
  198.               // Clear the screen
  199.               IGraphics->SetRast(RPort,0);
  200.               IGraphics->LoadRGB32(VPort,(ULONG *)Colours);
  201.               // Display the screen
  202.               IIntuition->ScreenToFront(BlankScreen);
  203.               PatternCount = 0;
  204.               // Wait for something to happen
  205.               IExec->Forbid();
  206.               BlankTask = (struct Task *)IExec->CreateTask("« FracBlank BlankerEntry Task »",127,BlankerEntry,16384 + 400 * MaxRecursionLevel,NULL);
  207.               IExec->SetSignal(0,SIG_HANDSHAKE);
  208.               IExec->Wait(SIG_HANDSHAKE);
  209.               IExec->Permit();
  210.             }
  211.             else {
  212.               IIntuition->CloseScreen(BlankScreen);
  213.               BlankScreen = NULL;
  214.             }
  215.           }
  216.         }
  217.         IExec->ReleaseSemaphore(&BlankSemaphore);
  218.       }
  219.       else {
  220.         // Push the blanker screen to the front if necessary
  221.         if (BlankScreen->TopEdge > 0) IIntuition->MoveScreen(BlankScreen,0,-BlankScreen->TopEdge);
  222.         if (IntuitionBase->FirstScreen != BlankScreen)  IIntuition->ScreenToFront(BlankScreen);
  223.         if (IntuitionBase->ActiveWindow != BlankWindow) IIntuition->ActivateWindow(BlankWindow);
  224.       }
  225.       SignalSet &= ~SIG_CHANGE;
  226.     }
  227.     // Change the patterns?
  228.     if (SignalSet & SIG_CHANGE) {
  229.       if (BlankTask) {
  230.         // Stop drawing patterns
  231.         StopDrawing = TRUE;
  232.         IExec->Signal(BlankTask,SIG_CHANGE);
  233.       }
  234.     }
  235.   }
  236.  
  237.   BlankerControlProcess = NULL;
  238.  
  239.   IExec->Signal((struct Task *)MainProcess,SIG_HANDSHAKE);
  240.  
  241. }
  242.  
  243. /* hsvramp():
  244.  *
  245.  *  Creates a ramp within HSV colour space, showing all
  246.  *  colours of the HSV circle.
  247.  */
  248.  
  249. void hsvramp(double h1, double s1, double b1, double h2, double s2, double b2, int count, UBYTE *red, UBYTE *green, UBYTE *blue) {
  250.  
  251.   double dh,ds,db;
  252.  
  253.   dh = (h2 - h1) / count;
  254.   ds = (s2 - s1) / count;
  255.   db = (b2 - b1) / count;
  256.  
  257.   while(count--) {
  258.     hsv2rgb(h1,s1,b1,red++,green++,blue++);
  259.     h1 += dh;
  260.     s1 += ds;
  261.     b1 += db;
  262.   }
  263.  
  264. }
  265.  
  266. /* hsv2rgb(double H,double S,double V,UBYTE *r,UBYTE *g,UBYTE *b):
  267.  *
  268.  *  Convert HSV (hue, saturation, value) colour index into
  269.  *  plain RGB (red, green, blue) colour space.
  270.  */
  271.  
  272. void hsv2rgb(double H, double S, double V, UBYTE *r, UBYTE *g, UBYTE *b) {
  273.  
  274.   int i;
  275.  
  276.   double f,
  277.          bb;
  278.  
  279.   UBYTE p,
  280.         q,
  281.         t;
  282.  
  283.   H -= floor(H);
  284.   H *= 6.0;
  285.   i = floor(H);
  286.   f = H - (double)i;
  287.   bb = 255.0 * V;
  288.  
  289.   p = (UBYTE)(bb * (1.0 - S));
  290.   q = (UBYTE)(bb * (1.0 - (S * f)));
  291.   t = (UBYTE)(bb * (1.0 - (S * (1.0 - f))));
  292.  
  293.   switch(i) {
  294.     case 0:  *r = (UBYTE)bb;
  295.       *g = t;
  296.       *b = p;
  297.       break;
  298.     case 1:  *r = q;
  299.       *g = (UBYTE)bb;
  300.       *b = p;
  301.       break;
  302.     case 2:  *r = p;
  303.       *g = (UBYTE)bb;
  304.       *b = t;
  305.       break;
  306.     case 3:  *r = p;
  307.       *g = q;
  308.       *b = (UBYTE)bb;
  309.       break;
  310.     case 4:  *r = t;
  311.       *g = p;
  312.       *b = (UBYTE)bb;
  313.       break;
  314.     case 5:  *r = (UBYTE)bb;
  315.       *g = p;
  316.       *b = q;
  317.       break;
  318.   }
  319.  
  320. }
  321.  
  322.